package cn.exempale.mscapplication.model.repository;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import cn.exempale.mscapplication.dto.TaskDTO;
import cn.exempale.mscapplication.emnus.ResultType;
import cn.exempale.mscapplication.emnus.StatusType;
import cn.exempale.mscapplication.model.db.entity.ResultEntity;
import cn.exempale.mscapplication.model.db.entity.TaskEntity;
import cn.exempale.mscapplication.model.net.callback.BaseCallBack;
import cn.exempale.mscapplication.model.net.callback.MCallBack;
import cn.exempale.mscapplication.constant.UrlConstant;
import cn.exempale.mscapplication.model.net.service.ApiService;
import cn.exempale.mscapplication.model.net.callback.Resource;
import cn.exempale.mscapplication.utils.RetrofitUtils;
import cn.exempale.mscapplication.vo.BasicResultVO;
import cn.exempale.mscapplication.vo.ProgressStatusVO;
import cn.exempale.mscapplication.vo.ResultVO;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * 通用接口调用
 */
public class NormalRepository extends BaseRepository {

    private ApiService apiService;
    private static NormalRepository instance;

    public static NormalRepository newInstance() {
        if (instance == null)
            instance = new NormalRepository();
        return instance;
    }

    private NormalRepository() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(UrlConstant.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .client(RetrofitUtils.normalClient())
                .build();
        apiService = retrofit.create(ApiService.class);
    }

    /**
     * 上传准备
     *
     * @param prepareDTO
     * @return
     */
    public Resource prepareUpload(Map<String, String> prepareDTO) {
        try {
            Response<BasicResultVO> response = apiService.prepareUpload(prepareDTO).execute();
            if (response.isSuccessful()) {
                BasicResultVO vo = response.body();
                if (ResultType.match(vo.getOk()) == ResultType.SUCCESS) {
                    return Resource.success(vo.getData());
                } else {
                    return Resource.error(vo.getFailed());
                }
            } else {
                return Resource.error("请示失败");
            }
        } catch (IOException ioException) {
            ioException.printStackTrace();
            return Resource.error("网络异常,请求失败");
        }
    }

    /**
     * 上传完毕合并
     *
     * @return
     */
    public Resource merge(Map<String, String> mergeDto) {
        try {
            Response<BasicResultVO> response = apiService.merge(mergeDto).execute();
            if (response.isSuccessful()) {
                BasicResultVO vo = response.body();
                if (ResultType.match(vo.getOk()) == ResultType.SUCCESS) {
                    return Resource.success(vo.getData());
                } else {
                    return Resource.error(vo.getFailed());
                }
            } else {
                return Resource.error("请示失败");
            }
        } catch (IOException ioException) {
            ioException.printStackTrace();
            return Resource.error("网络异常,请求失败");
        }
    }

    /**
     * 获取任务进度
     *
     * @param taskDTO
     * @return
     */
    public Resource<ProgressStatusVO> getProgress(Map<String, String> taskDTO) {
        try {
            Response<BasicResultVO> response = apiService.getProgress(taskDTO).execute();
            if (response.isSuccessful()) {
                BasicResultVO vo = response.body();
                if (ResultType.match(vo.getOk()) == ResultType.SUCCESS) {
                    String json = vo.getData();
                    ProgressStatusVO statusVO = new Gson().fromJson(json, ProgressStatusVO.class);
                    return Resource.success(statusVO);
                } else {
                    return Resource.error(vo.getFailed());
                }
            } else {
                return Resource.error("请示失败");
            }
        } catch (IOException ioException) {
            ioException.printStackTrace();
            return Resource.error("网络异常,请求失败");
        }
    }

    /**
     * 获取结果
     *
     * @param taskDTO
     * @return
     */
    public Resource<List<ResultVO>> getResult(Map<String, String> taskDTO) {
        try {
            Response<BasicResultVO> response = apiService.getResult(taskDTO).execute();
            if (response.isSuccessful()) {
                BasicResultVO vo = response.body();
                if (ResultType.match(vo.getOk()) == ResultType.SUCCESS) {
                    String json = vo.getData();
                    List<ResultVO> vos = new Gson().fromJson(json, new TypeToken<List<ResultVO>>() {
                    }.getType());
                    // 更新数据库
                    updateDb(vos, taskDTO);
                    return Resource.success(vos);
                } else {
                    return Resource.error(vo.getFailed());
                }
            } else {
                return Resource.error("请示失败");
            }
        } catch (IOException ioException) {
            ioException.printStackTrace();
            return Resource.error("网络异常,请求失败");
        }
    }

    /**
     * 更新数据库
     *
     * @param vos
     */
    private void updateDb(List<ResultVO> vos, Map<String, String> taskDTO) {
        // 任务dto
        String json = new Gson().toJson(taskDTO);
        TaskDTO dto = new Gson().fromJson(json, TaskDTO.class);
        // todo 修改任务数据库，保存文件创建时间即通话时间
        long crateTime = Long.parseLong(dto.getTs());
        // 结果
        List<ResultEntity> results = new ArrayList<>();
        ResultEntity lastEntity = new ResultEntity();
        for (ResultVO vo : vos) {
            if (vo.getSpeaker().equals(lastEntity.getSpeaker())) {
                // 合并
                String content = lastEntity.getContent();
                content += vo.getOnebest();
                lastEntity.setContent(content);
                results.remove(results.size() - 1);
                results.add(lastEntity);
            } else {
                // 新增
                ResultEntity entity = new ResultEntity();
                entity.setSpeaker(vo.getSpeaker());
                entity.setContent(vo.getOnebest());
                entity.setTaskId(dto.getTask_id());
                long startTime = crateTime + vo.getBg();
                entity.setSpeakTime(new Date(startTime));
                lastEntity = entity;
                results.add(entity);
            }
        }
        // 用户结果显示
        for (ResultEntity entity : results) {
            String speaker = entity.getSpeaker();
            speaker = "用户" + speaker;
            entity.setSpeaker(speaker);
        }
        executor.execute(() -> resultDAO.save(results.toArray(new ResultEntity[0])));
    }

    public LiveData<List<TaskEntity>> getAllTasks(int deleted) {
        return taskDAO.findAll(deleted);
    }
}
